/**
  * Author: Mei
  * Date: 2020-12-13 15:11
  * Description:
  * C++标准库是大于STL
  * C++标准库的头文件是不带.h
  * 新式头文件不带.h 如#include<cstdio>
  * 旧式也可以用
  *
  */
#include "../../head.h"

using namespace std;

template<typename Foo, typename Argv>
typename std::result_of<Foo(Argv)>::type invoke(Foo f, Argv a) {
    return f(a);
};

template<typename Foo, typename Argv>
auto invoke1(Foo f, Argv a) ->decltype(f(a)) {
    return f(a);
};

template<typename Foo, typename Argv>
auto invoke3(Foo f, Argv a) -> decltype(Foo()(a)) { //Foo()生成临时对象
    return f(a);
}
int max1(int a, int b) {
    return a + b +
           1;
}

int max2(int a) {
    return a + 1;
}

int main() {
    /**
     * STL六大部件（Components)
     * 容器（Containers）
     * 分配器（Allocators）
     * 算法（Algorithms）
     * 迭代器（Iterators）
     * 适配器（Adapters）
     * 仿函数（Functors）
     *
     * 数据结构+算法
     */
    int arr[6] = {123, 23, 223, 12, 50, 3};
    vector<int> vec{1, 2, 3, 4, 5};
    vector<int, allocator<int>> vi(arr, arr + 6); //分配器 不写就有默认
    std::function<bool(int)> less_than = [](int x){ return x <= 5; };
    cout << count_if(vi.begin(), vi.end(),
                     //not1(bind2nd(less<int>(), 40)))  //bind2nd适配器  not1小于40的否定
                     //not1(less_than))  //bind2nd适配器  not1小于40的否定
                     not1([](int n) -> bool {
                         return n < 40;
                     }))

         //         [](int x) -> bool {
         //             return x < 50;
         //         })
         << endl;

    cout << invoke3(max2, 3) << endl;
    std::vector<int> nums = {5, 3, 4, 9, 1, 7, 6, 2, 8};
    std::function<bool(int)> less_than_5 = [](int x){ return x <= 5; };
    // count numbers of integer that not less and equal than 5
    std::cout << std::count_if(nums.begin(), nums.end(), std::not1(less_than_5)) << "\n";

    return 0;
}